package com.yzt.zhuju.widget.emticonnskeyboard;

import android.content.Context;
import android.text.Editable;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.text.style.ForegroundColorSpan;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.View;

import androidx.appcompat.widget.AppCompatEditText;

import com.yzt.zhuju.widget.emticonnskeyboard.interfaces.EmoticonFilter;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * use XhsEmotionsKeyboard(https://github.com/w446108264/XhsEmoticonsKeyboard)
 * author: sj
 */
public class EmoticonsEditText extends AppCompatEditText {

    private List<EmoticonFilter> mFilterList;
    private TextWatcher watcher;
    private String TAG = "EmoticonsEditText";

    public static final char AT_PERSON_MARK = 8197;//特殊空格
    protected int libleColor = 0xff3480ff;
    protected StringBuilder builder;

    public EmoticonsEditText(Context context) {
        this(context, null);
    }

    public EmoticonsEditText(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public EmoticonsEditText(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }


    public void deleteChar(){
//        try {
//            int index = this.getSelectionStart();
//            if (index <= 0) return;
//
//            Editable editable = this.getText();
//            ImageSpan[] spans = editable.getSpans(0, index - 1, ImageSpan.class);
//            int st = index - 1;
//            int en = index;
//            if (spans != null && spans.length > 0) {
//
//                int spanEnd = editable.getSpanEnd(spans[spans.length - 1]);
//                int spanBegin = editable.getSpanStart(spans[spans.length - 1]);
//
//                if (spanEnd == index) {
//                    st = spanBegin;
//                    en = spanEnd;
//                }
//            }
//
        //还需要判断emoji的两个字符的问题，用下面的方法了
//            editable.delete(st, en);
//        }catch (Exception e){}

        int keyCode =KeyEvent.KEYCODE_DEL;
        KeyEvent keyEventDown = new KeyEvent(KeyEvent.ACTION_DOWN, keyCode);
        KeyEvent keyEventUp = new KeyEvent(KeyEvent.ACTION_UP, keyCode);
        this.onKeyDown(keyCode, keyEventDown);
        this.onKeyUp(keyCode, keyEventUp);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        try {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        } catch (ArrayIndexOutOfBoundsException e) {
            setText(getText().toString());
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        if(oldh > 0 && onSizeChangedListener != null){
            onSizeChangedListener.onSizeChanged(w, h, oldw, oldh);
        }
    }

    @Override
    public void setGravity(int gravity) {
        try {
            super.setGravity(gravity);
        } catch (ArrayIndexOutOfBoundsException e) {
            setText(getText().toString());
            super.setGravity(gravity);
        }
    }

    @Override
    public void setText(CharSequence text, BufferType type) {
        try {
            super.setText(text, type);
        } catch (ArrayIndexOutOfBoundsException e) {
            setText(text.toString());
        }
    }


    @Override
    protected final void onTextChanged(CharSequence arg0, int start, int lengthBefore, int after) {
        super.onTextChanged(arg0, start, lengthBefore, after);
        if(mFilterList == null){
            return;
        }
        for(EmoticonFilter emoticonFilter : mFilterList) {
            emoticonFilter.filter(this, arg0, start, lengthBefore, after);
        }
    }

    public void addEmoticonFilter(EmoticonFilter emoticonFilter){
        if(mFilterList == null){
            mFilterList = new ArrayList<>();
        }
        mFilterList.add(emoticonFilter);
    }

    public void removedEmoticonFilter(EmoticonFilter emoticonFilter){
        if(mFilterList != null && mFilterList.contains(emoticonFilter)){
            mFilterList.remove(emoticonFilter);
        }
    }

    @Override
    public boolean dispatchKeyEventPreIme(KeyEvent event) {
        if(onBackKeyClickListener != null){
            onBackKeyClickListener.onBackKeyClick();
        }
        return super.dispatchKeyEventPreIme(event);
    }

    @Override
    public boolean performClick() {
        return super.performClick();
    }

    public interface OnBackKeyClickListener {
        void onBackKeyClick();
    }

    OnBackKeyClickListener onBackKeyClickListener;

    public void setOnBackKeyClickListener(OnBackKeyClickListener i) {
        onBackKeyClickListener = i;
    }

    public interface OnSizeChangedListener {
        void onSizeChanged(int w, int h, int oldw, int oldh);
    }

    OnSizeChangedListener onSizeChangedListener;

    public void setOnSizeChangedListener(OnSizeChangedListener i) {
        onSizeChangedListener = i;
    }

    /**
     * 插入一个Span块
     *
     * @param bean
     */
    public void addLibleSpan(CommTextSpan bean) {
        builder = new StringBuilder();
        if (TextUtils.isEmpty(bean.getShowText())) {
            return;
        } else {
            builder.append(bean.getShowText()).append(AT_PERSON_MARK);
        }
        getText().insert(getText().length(), builder.toString());
        SpannableString sps = new SpannableString(getText());
        int start = getText().length() - builder.toString().length();
        int end = getText().length();
        bean.setStart(start);
        bean.setEnd(end);
        bean.setShowText(builder.toString());
        setLabelSpan(sps, bean);
        //设置内容到输入框
        setText(sps);
        //光标定位在插入内容后的位置
        setSelection(end);
    }

    /**
     * 设置内容颜色
     *
     * @param sps
     * @param bean
     */
    private void setLabelSpan(Spannable sps, CommTextSpan bean) {
        sps.setSpan(bean, bean.getStart(), bean.getEnd(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        if (bean.getSpanColor()==0){
            sps.setSpan(new ForegroundColorSpan(libleColor), bean.getStart(), bean.getEnd(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        }else {
            sps.setSpan(new ForegroundColorSpan(bean.getSpanColor()), bean.getStart(), bean.getEnd(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        }
    }

    /**
     * 设置删除span的代码
     */
    public void setSpanDelete() {
        setOnKeyListener(new View.OnKeyListener() {
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                if (keyCode == KeyEvent.KEYCODE_DEL && event.getAction() == KeyEvent.ACTION_DOWN) {

                    int selectionStart = getSelectionStart();

                    CommTextSpan[] atSpans = getText().getSpans(0, getSelectionEnd(), CommTextSpan.class);
                    int length = atSpans.length;

                    if (0 == length) {
                        return false;
                    }
                    for (CommTextSpan atSpan : atSpans) {
                        int start = getText().getSpanStart(atSpan);
                        int end = getText().getSpanEnd(atSpan);
                        if (selectionStart >= start && selectionStart <= end) {
                            getText().delete(start, end);
                            return true;
                        }
                    }
                }
                return false;
            }
        });
    }

    /**
     * 获取EditText的数据
     *
     */
    public List<CommTextSpan> getSpanTextList() {
        ArrayList<CommTextSpan> textSpanList = new ArrayList<>();
        CommTextSpan[] spans = getText().getSpans(0, getSelectionEnd(), CommTextSpan.class);
        List<CommTextSpan> myTextSpans = sortByIndex(getText(), spans);
        int currentIndex = 0;
        for (CommTextSpan span : myTextSpans) {
            int startIndex = getText().getSpanStart(span);
            int endIndex = getText().getSpanEnd(span);
            if (currentIndex < startIndex) {
                //EditText中Span前文本内容
                textSpanList.add(new CommTextSpan(getText().subSequence(currentIndex, startIndex).toString()));
            }
            //EditText中span内容
            textSpanList.add(new CommTextSpan(span.getShowText(), span.getLibleId(), span.getLibleName(), span.getType(), span.getNewType()));
            currentIndex = endIndex;
        }
        if (currentIndex < getText().length()) {
            //Span后文本内容
            textSpanList.add(new CommTextSpan(getText().subSequence(currentIndex, getText().length()).toString()));
        }
        return textSpanList;
    }


    /**
     * 将数组转换为List
     *
     * @param editInput
     * @param array
     * @return
     */
    private List<CommTextSpan> sortByIndex(final Editable editInput, CommTextSpan[] array) {
        ArrayList<CommTextSpan> sortList = new ArrayList<>();
        for (CommTextSpan span : array) {
            sortList.add(span);
        }
        Collections.sort(sortList, new Comparator<CommTextSpan>() {
            @Override
            public int compare(CommTextSpan lhs, CommTextSpan rhs) {
                return editInput.getSpanStart(lhs) - editInput.getSpanStart(rhs);
            }
        });
        return sortList;
    }

}